package com.zhima.util;

import java.io.File;
import java.util.List;

/**
 * @author : 芝麻
 * @date : 2023-08-05 16:49
 **/
public interface LanguageExecutor {
    /**
     * C 的编译器
     */
    String C_COMPILER_NAME = "gcc";
    /**
     * C++ 的编译器
     */
    String C_PLUS_COMPILER_NAME = "g++";
    /**
     * JAVA 的编译器
     */
    String JAVA_COMPILER_NAME = "javac";
    /**
     * class 文件的执行器
     */
    String JAVA_RUNNER = "java";
    /**
     * py 文件的解释器
     */
    String PY_RUNNER = "py";

    private static List<String> runCOrCPlusCode(String codeFilePath, List<String> inputDatas, String compilerName) {
        String[] es = LanguageExecutor.splitCodeFilePath(codeFilePath);
        String codeFileBaseDir = es[0];
        String codeFileNameWithoutSuffix = es[1];
        SystemCommandUtil.execForResults(
                // 先切盘！
                String.format("%s:", codeFileBaseDir.charAt(0)),
                // 进入代码文件的同级目录
                String.format("cd %s", codeFileBaseDir),
                String.format("%s -o %s.exe %s", compilerName, codeFileNameWithoutSuffix, codeFilePath)
        );
        // 编译后的文件应该交给上层去删除
        // FileUtil.deleteFileOnExit(String.format("%s%s%s.exe", codeFileBaseDir, File.separator, codeFileNameWithoutSuffix));
        String exeFilePath = String.format("%s%s%s.exe", codeFileBaseDir, File.separator, codeFileNameWithoutSuffix);
        List<String> results = SystemCommandUtil.execForResults(
                inputDatas,
                exeFilePath
        );
        results.add(exeFilePath);
        return results;
    }

    /**
     * 将代码文件拆分成两个部分
     * 第一个部分是文件的根路径
     * 第二个部分是不带后缀名的文件名
     *
     * @param codeFilePath
     * @return
     */
    static String[] splitCodeFilePath(String codeFilePath) {
        int pointIndex = -1;
        int separatorIndex = -1;
        char[] cArray = codeFilePath.toCharArray();
        for (int i = 0; i < cArray.length; i++) {
            char currChar = codeFilePath.charAt(i);
            if (currChar == '.') {
                pointIndex = i;
            } else if (currChar == File.separatorChar) {
                separatorIndex = i;
            }
        }
        if (pointIndex == -1 || separatorIndex == -1) {
            throw new IllegalArgumentException("路径参数错误");
        }
        return new String[]{new String(cArray, 0, separatorIndex), new String(cArray, separatorIndex + 1, pointIndex - separatorIndex - 1)};
    }

    /**
     * 具体运行代码的逻辑交给子类实现
     *
     * @param codeFilePath
     * @param inputDatas
     * @return
     */
    List<String> runCode(String codeFilePath, List<String> inputDatas);

    enum Language implements LanguageExecutor {
        JAVA {
            @Override
            public List<String> runCode(String codeFilePath, List<String> inputDatas) {
                String[] es = LanguageExecutor.splitCodeFilePath(codeFilePath);
                String codeFileBaseDir = es[0];
                String codeFileNameWithoutSuffix = es[1];
                SystemCommandUtil.execForResults(String.format("%s -encoding utf8 %s", JAVA_COMPILER_NAME, codeFilePath));
                // 编译后的文件应该交给上层去删除
                // FileUtil.deleteFileOnExit(String.format("%s%s%s.class", codeFileBaseDir, File.separator, codeFileNameWithoutSuffix));
                List<String> results = SystemCommandUtil.execForResults(
                        inputDatas,
                        // 先切盘！
                        String.format("%s:", codeFilePath.charAt(0)),
                        String.format("cd %s", codeFileBaseDir),
                        String.format("%s %s", JAVA_RUNNER, codeFileNameWithoutSuffix)
                );
                // 这个文件是需要删除的
                results.add(String.format("%s%s%s.class", codeFileBaseDir, File.separator, codeFileNameWithoutSuffix));
                return results;
            }
        }, CPP {
            @Override
            public List<String> runCode(String codeFilePath, List<String> inputDatas) {
                return runCOrCPlusCode(codeFilePath, inputDatas, C_PLUS_COMPILER_NAME);
            }
        }, C {
            @Override
            public List<String> runCode(String codeFilePath, List<String> inputDatas) {
                return runCOrCPlusCode(codeFilePath, inputDatas, C_COMPILER_NAME);
            }
        }, PY {
            @Override
            public List<String> runCode(String codeFilePath, List<String> inputDatas) {
                List<String> results = SystemCommandUtil.execForResults(
                        inputDatas,
                        // 先切盘！
                        String.format("%s:", codeFilePath.charAt(0)),
                        String.format("%s %s", PY_RUNNER, codeFilePath)
                );
                // 需要对齐功能
                results.add("");
                return results;
            }
        };
    }
}
